/**
 * -- Stroage 模块 --
 * 用于管理Storage
 */

if (typeof (window.localStorage) == 'undefined' || typeof (window.sessionStorage) == 'undefined' || typeof (document.cookie) == 'undefined') {
	console.error('[web-tool storage model] window.localStorage or window.sessionStorage or document.cookie is undefined')
}

/**
 * 全局配置项
 */
export interface Setting {
	/**
	 * 全局前缀
	 */
	prefix: string,
	/**
	 * 默认超时时间，0不限制
	 */
	default_expire_time: number,
	/**
	 * 是否在每次get()时自动清除已过期的
	 */
	auto_clear_expired: boolean,
}


let setting: Setting = {
	prefix: '', //全局前缀
	default_expire_time: 0, //有效时间，0永久有效，>0是秒数
	auto_clear_expired: true, //是否自动清除过期的
}

export interface ConfigOptions {
	/**
	 * 全局前缀
	 */
	prefix?: string,
	/**
	 * 默认超时时间，0不限制
	 */
	default_expire_time?: number,
	/**
	 * 是否在每次get()时自动清除已过期的
	 */
	auto_clear_expired?: boolean,
}

/**
 * 设置全局配置项
 * @param {object} options 
 */
export const config = (options: ConfigOptions): void => {
	Object.keys(setting).forEach(key => {
		if (options.hasOwnProperty(key)) setting[key] = options[key];
	})
}

/**
 * 数据转换器
 */
const DataParse = {
	// 存入
	in: (data, expire_time = 0) => {
		let data_type = typeof data;
		let input_data = {
			data_type: data_type,
			data: data,
			create_time: new Date().valueOf(),
			expire_time: expire_time,
		};
		return JSON.stringify(input_data);
	},
	// 取出
	out: (data) => {
		let out = null;
		try {
			out = JSON.parse(data);
		} catch (e) { }
		return out
	},
	// 检查有效期，若expire_time传入false或0，直接返回true
	check_expire: (expire_time, create_time) => {
		if (!expire_time) return true;
		return create_time + (expire_time * 1000) >= new Date().valueOf();
	}
}

export interface Storage {
	get: (key: null | string, force_prefix?: null | string) => any,
	set: (key: string, val: any, expire_time?: number, force_prefix?: null | string) => Storage,
	all: (force_prefix?: null | string) => object,
	remove: (key?: null | string, force_prefix?: null | string) => Storage
}

export const local: Storage = {
	get: function (key = null, force_prefix = null) {
		let prefix = force_prefix === null ? setting.prefix : force_prefix;
		if (typeof (key) === null) return this.all(prefix);

		let item = DataParse.out(window.localStorage.getItem(prefix + key));
		if (!item) return null;
		if (!DataParse.check_expire(item.expire_time, item.create_time)) {
			if (setting.auto_clear_expired) {
				// 自动清除过期
				this.remove(key, prefix);
			}
			return null;
		}
		return item.data;
	},
	/**
	 * 设置storage
	 * @param {string} key 键名
	 * @param {any} val 键值 
	 * @param {number} expire_time 过期时间（>=0），0表示无限，单位秒
	 * @param {string} force_prefix 强制设置前缀
	 */
	set: function (key, val, expire_time = 0, force_prefix = null) {
		let prefix = force_prefix === null ? setting.prefix : force_prefix;
		window.localStorage.setItem(prefix + key, DataParse.in(val, expire_time));
		return this;
	},
	all: function (force_prefix = null) {
		let obj = {};
		let prefix = force_prefix === null ? setting.prefix : force_prefix;
		for (let i = 0; i < window.localStorage.length; i++) {
			let key = window.localStorage.key(i); //获取本地存储的Key
			if (key.indexOf(prefix) === 0) {
				let item = this.get(key, prefix);
				if (item) obj[key] = item;
			}
		}
		return obj;
	},
	remove: function (key = null, force_prefix = null) {
		let prefix = force_prefix === null ? setting.prefix : force_prefix;
		if (key === null) {
			// 移除全部
			if (!prefix) {
				// 移除全部
				window.localStorage.clear()
			} else {
				// 移除指定前缀
				for (let i = 0; i < window.localStorage.length; i++) {
					let find_key = window.localStorage.key(i); //获取本地存储的Key
					if (find_key.indexOf(prefix) === 0) {
						window.localStorage.removeItem(find_key);
					}
				}
			}
		} else {
			// 移除指定
			window.localStorage.removeItem(prefix + key);
		}
		return this;
	},
}

export const session: Storage = {
	get: function (key: null | string = null, force_prefix: null | string = null) {
		let prefix = force_prefix === null ? setting.prefix : force_prefix;
		if (key === null) return this.all(prefix);

		let item = DataParse.out(window.sessionStorage.getItem(prefix + key));
		if (!item) return null;
		if (!DataParse.check_expire(item.expire_time, item.create_time)) {
			if (setting.auto_clear_expired) {
				// 自动清除过期
				this.remove(key, prefix);
			}
			return null;
		}
		return item.data;
	},
	set: function (key: string, val: any, expire_time = 0, force_prefix = null) {
		let prefix = force_prefix === null ? setting.prefix : force_prefix;
		window.sessionStorage.setItem(prefix + key, DataParse.in(val, expire_time));
		return this;
	},
	all: function (force_prefix = null) {
		let obj = {};
		let prefix = force_prefix === null ? setting.prefix : force_prefix;
		for (let i = 0; i < window.sessionStorage.length; i++) {
			let key = window.sessionStorage.key(i); //获取本地存储的Key
			if (key.indexOf(prefix) === 0) {
				let item = this.get(key, prefix);
				if (item) obj[key] = item;
			}
		}
		return obj;
	},
	remove: function (key = null, force_prefix = null) {
		let prefix = force_prefix === null ? setting.prefix : force_prefix;
		if (key === null) {
			// 移除全部
			if (!prefix) {
				// 移除全部
				window.sessionStorage.clear()
			} else {
				// 移除指定前缀
				for (let i = 0; i < window.sessionStorage.length; i++) {
					let find_key = window.sessionStorage.key(i); //获取本地存储的Key
					if (find_key.indexOf(prefix) === 0) {
						window.sessionStorage.removeItem(find_key);
					}
				}
			}
		} else {
			// 移除指定
			window.sessionStorage.removeItem(prefix + key);
		}
		return this;
	}
}